####################################################################################
# Replication files for appendix analyses in Communicating the Politics of the Law # 
####################################################################################
# Loading required packages
library(lfe); library(rms); library(stargazer); library(tidyverse); library(xtable)

# Loading the data
# Release level
load("release_level_data.RData")
# Senator level
load("senator_level_data.RData")
# Abortion paragraph level
load("abortion_paragraph_level_data.RData")
# Abortion document level
load("abortion_release_level_data.RData")
# Abortion senator-year level
load("abortion_senator_level_data.RData")
# Topic model objects
load("topic_model_objects.RData")

#############################################################
# Appendix Section B.1 discussion of case discussion volume #
#############################################################
# Percentage of press releases that reference at least one case with v. (or variants) or a common party name
round(prop.table(table(releases$explicit_mention)), 3)

# Percentage of press releases that reference a case, including key topic words (e.g., "abortion" for Hellerstedt in 2016)
round(prop.table(table(releases$explicit_or_keyword_mention)), 3)

##############################################################
# Table E.1: Descriptive Statistics of Variables (All Cases) #
##############################################################
# Extracting the variables we want and creating a new data frame
senator_data_year_df_slim <- senator_data_year %>%
  select(majority_party,
         seniority,
         freshman,
         senator_lawyer,
         on_sjc,
         extremity,
         marginal,
         up_for_election,
         case_count,
         republican,
         post_2018,
         any_case_message) %>%
  data.frame()

# Clean names for variables
colnames(senator_data_year_df_slim) <- c("Majority Party","Seniority","Freshman","Lawyer","On Judiciary Committee","Extremity","Marginal Senator","Up for Election","Number of Cases from State","Republican","Post-2018","Any Message")

# Creating the table
stargazer(senator_data_year_df_slim, label="descriptive_variables", title="Descriptive Statistics of Variables (All Cases)")

#######################################################################
# Table E.2: Descriptive Statistics of Variables (Abortion Messaging) #
#######################################################################
# Slimming the paragraph-level data to variables we want
paragraph_level_df <- data.frame(senate_para_abortion)
paragraph_level_df_slim <- paragraph_level_df[,c("majority_party","seniority","freshman","senator_lawyer","on_sjc",
                                                 "legal_language","message_length","marginal","up_for_election","republican","post_2018","extremity","act")]
# Renaming variables for ease
colnames(paragraph_level_df_slim) <- c("Majority Party","Seniority","Freshman","Lawyer","On Judiciary Committee","Legal Rhetoric","Message Length","Marginal Senator",
                                       "Up for Election","Republican","Post-2018","Extremity","Legislative Rhetoric")
# Making the descriptive table
stargazer(paragraph_level_df_slim, label="descriptive_variables_2", title="Descriptive Statistics of Variables (Abortion Messaging)")

#######################################
# Table F.1: Binary Senator Messaging #
#######################################
# Running a model with binary message as outcome, year and state fixed effects, clustering by state
binary1 <- felm(any_case_message ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                  on_sjc + senator_lawyer + seniority + seniority.squared + freshman + case_count|year+
                  two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)
# Running a model with binary message as outcome, year and senator fixed effects, clustering by senator
binary1_b <- felm(any_case_message ~ majority_party + marginal * up_for_election + on_sjc + freshman + case_count|year+last.name|0|last.name, data = senator_data_year)

# Stargazer table of results
stargazer(binary1, binary1_b,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "Number of Cases from State",
                               "Republican x Post-2018",
                               "Marginal x Up for Election"),
          dep.var.labels = c("Any Message"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", ""),
                           c("Senator FEs", "", "\\checkmark"),
                           c("SE Cluster", "State", "Senator")),
          title = "Binary Senator Messaging About Supreme Court Cases, 2012--2024",
          label = "sen_level_binary")

##################################################
# Table F.2: Alternative Seniority Specification #
##################################################
# Number of messages outcome, linear measure of seniority only (no squared term), year and state fixed effects, clustering by state
case1_seniority <- felm(case_messages ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                          on_sjc + senator_lawyer + seniority + freshman + case_count|year+
                          two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)
# Message length outcome, linear measure of seniority only (no squared term), year and state fixed effects, clustering by state
length1_seniority <- felm(log_message_length ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                            on_sjc + senator_lawyer + seniority + freshman + case_count|year+
                            two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)

# Stargazer table of results
stargazer(case1_seniority, length1_seniority,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Freshman",
                               "Number of Cases from State",
                               "Republican x Post-2018",
                               "Marginal x Up for Election"),
          dep.var.labels = c("\\# Messages", "ln(Total Message Length)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark"),
                           #c("Senator FEs", "", "\\checkmark", "", "\\checkmark"),
                           c("SE Cluster", "State", "State")),
          title = "Senator Messaging about Supreme Court Cases, Alternative Seniority Specification",
          label = "sen_level_felm_only_linear_seniority")

####################################
# Table F.3: No Freshman Indicator #
####################################
# Number of messages outcome, no freshman dummy, year and state fixed effects, clustering by state
case1_no_freshman <- felm(case_messages ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                            on_sjc + senator_lawyer + seniority + seniority.squared + case_count|year+
                            two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)
# Message length outcome, no freshman dummy, year and state fixed effects, clustering by state
length1_no_freshman <- felm(log_message_length ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                              on_sjc + senator_lawyer + seniority + seniority.squared + case_count|year+
                              two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)

# Stargazer table of results
stargazer(case1_no_freshman, length1_no_freshman,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Number of Cases from State",
                               "Republican x Post-2018",
                               "Marginal x Up for Election"),
          dep.var.labels = c("\\# Messages", "ln(Total Message Length)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark"),
                           #c("Senator FEs", "", "\\checkmark", "", "\\checkmark"),
                           c("SE Cluster", "State", "State")),
          title = "Senator Messaging about Supreme Court Cases, No Freshman Indicator",
          label = "sen_level_felm_no_freshman")

##############################################
# Table F.4: Alternative Marginality Measure #
##############################################
# Number of messages, alternative marginality measure, year and state fixed effects, clustering by state
case1_alt_marginal <- felm(case_messages ~ republican + republican:post_2018 + majority_party + log_previous_vote_share * up_for_election + extremity + 
                             on_sjc + senator_lawyer + seniority + seniority.squared + freshman + case_count|year+
                             two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)
# Number of messages, alternative marginality measure, year and senator fixed effects, clustering by senator
case1_b_alt_marginal <- felm(case_messages ~ majority_party + log_previous_vote_share * up_for_election + on_sjc + freshman + case_count|year+
                               last.name|0|last.name, data = senator_data_year)

# Length, alternative marginality measure, year and state fixed effects, clustering by state
length1_alt_marginal <- felm(log_message_length ~ republican + republican:post_2018 + majority_party + log_previous_vote_share * up_for_election + extremity + 
                               on_sjc + senator_lawyer + seniority + seniority.squared + freshman + case_count|year+
                               two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senator_data_year)
# Length, alternative marginality measure, year and senator fixed effects, clustering by senator
length1_b_alt_marginal <- felm(log_message_length ~ majority_party + log_previous_vote_share * up_for_election + on_sjc + freshman + case_count|year+
                                 last.name|0|last.name, data = senator_data_year)

# List of models to feed into stargazer table
models_list <- list(case1_alt_marginal, case1_b_alt_marginal, length1_alt_marginal, length1_b_alt_marginal)
# Stargazer table of results
stargazer(models_list,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Previous Vote Share (Log)",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "Number of Cases from State",
                               "Republican x Post-2018",
                               "Previous Vote Share (Log) x Up for Election"),
          dep.var.labels = c("\\# Messages", "ln(Total Message Length)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "", "\\checkmark", ""),
                           c("Senator FEs", "", "\\checkmark", "", "\\checkmark"),
                           c("SE Cluster", "State", "Senator", "State", "Senator")),
          title = "Senator Messaging about Supreme Court Cases, Alternative Marginality Measure",
          label = "sen_level_felm_alt_marginal")

###############################
# Table H.1: Paragraph Topics #
###############################
# Joins the most likely topics dataset to our paragraph-level data
senate_topics_abortion <- senate_para_abortion %>%
  left_join(topics_tbl)

# Takes this dataset, groups by topic, adds in topic top terms, summarizes proportion of legal and legislative language and republican and sample size
senate_topics_abortion %>%
  group_by(topic) %>%
  dplyr::summarize(legal_language = mean(legal_language),
                   act = mean(act),
                   republican = mean(republican),
                   n = n()) %>%
  # Adds in 6 most likely terms
  left_join(terms_tbl) %>%
  # Removes an NA
  filter(! is.na(topic)) %>%
  # Arrange by number of paragraphs in topic
  arrange(desc(n)) %>%
  # Determining if topic is above mean in legal language, legislative language, Republican messaging
  mutate(high_legal_language = ifelse(legal_language > mean(legal_language), 1, 0),
         high_act = ifelse(act > mean(act), 1, 0),
         high_republican = ifelse(republican > mean(republican), 1, 0)) %>%
  # Rounding legal and legislative language to 2 decimals, bolding high-volume legal, legislative, Republican messaging
  mutate(legal_language = as.character(round(legal_language, 2)),
         legal_language = ifelse(high_legal_language == 1, paste0("\\textbf{", legal_language, "}"), legal_language),
         act = as.character(round(act, 2)),
         act = ifelse(high_act == 1, paste0("\\textbf{", act, "}"), act),
         republican = as.character(round(republican, 2)),
         republican = ifelse(high_republican == 1, paste0("\\textbf{", republican, "}"), republican),
         words = gsub("_", "\\\\_", words)) %>%
  # Selecting what we want to put in the table
  select(words, n, legal_language, act, republican) %>%
  rename(N = n,
         Legal = legal_language,
         Legislative = act,
         Republican = republican,
         `Top words/terms` = words) %>%
  xtable(caption = "Paragraph Topics in Abortion Case Press Releases (From LDA Model)",
         label = "lda") %>%
  print(include.rownames = FALSE,
        caption.placement = "top",
        size = "footnotesize",
        sanitize.text.function = identity)

################################################
# Table H.2: Legal Rhetoric, Additional Models #
################################################
# Document-level model of binary use of legal language, year and state fixed effects, state clustering
doc_level <- felm(legal_language ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity +
                    on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                    two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_document_abortion)
# Document-level model of proportion of paragraphs that are legal language, year and state fixed effects, state clustering
doc_level_prop <- felm(legal_language_prop ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                         on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                         two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_document_abortion)
# Senator-year level model of binary use of legal language, year and state fixed effects, state clustering
sen_year <- felm(legal_language ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                   on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                   two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_senator_year_abortion)
# Senator-year level model of proportion of paragraphs that are legal language, year and state fixed effects, state clustering
sen_year_prop <- felm(legal_language_prop ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                        on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                        two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_senator_year_abortion)

# Stargazer table of results
stargazer(doc_level, sen_year, doc_level_prop, sen_year_prop,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "ln(Message Length)",
                               "Republican x Post-2018",
                               "Marginal x Up for Election"),
          dep.var.labels = c("Legal Rhetoric (Binary)", "Legal Rhetoric (Proportion)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("State-clustered SEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("Unit of Analysis", "Document", "Senator-year", "Document", "Senator-year")),
          title = "Legal Rhetoric in Senator Messaging about Abortion Cases",
          label = "abortion_felm",
          font.size = "footnotesize")

######################################################
# Table H.3: Legislative Rhetoric, Additional Models #
######################################################
# Document-level model of binary use of legislative language, year and state fixed effects, state clustering
doc_level2 <- felm(act ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                     on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                     two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_document_abortion)
# Document-level model of proportion of paragraphs that are legislative language, year and state fixed effects, state clustering
doc_level_prop2 <- felm(act_prop ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                          on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                          two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_document_abortion)
# Senator-year level model of binary use of legislative language, year and state fixed effects, state clustering
sen_year2 <- felm(act ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                    on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                    two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_senator_year_abortion)
# Senator-year level model of proportion of paragraphs that are legislative language, year and state fixed effects, state clustering
sen_year_prop2 <- felm(act_prop ~ republican + republican:post_2018 + majority_party + marginal * up_for_election + extremity + 
                         on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_sum_message_length|year+
                         two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_senator_year_abortion)

# Stargazer table of results
stargazer(doc_level2, sen_year2, doc_level_prop2, sen_year_prop2,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "ln(Message Length)",
                               "Republican x Post-2018",
                               "Marginal x Up for Election"),
          dep.var.labels = c("Legislative Rhetoric (Binary)", "Legislative Rhetoric (Proportion)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("State-clustered SEs", "\\checkmark", "\\checkmark", "\\checkmark", "\\checkmark"),
                           c("Unit of Analysis", "Document", "Senator-year", "Document", "Senator-year")),
          title = "Legislative Rhetoric in Senator Messaging about Abortion Cases",
          label = "abortion_felm_act",
          font.size = "footnotesize")

##################################################################
# Table H.4: Legal and Legislative Rhetoric, Logistic Regression #
##################################################################
# Paragraph-level regression of use of legal language as function of theoretical predictors; logistic regression; year and state fixed effects
para_level_logit_legal <- lrm(legal_language ~ republican + republican_post_2018 + majority_party + marginal * up_for_election + extremity + 
                                on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_message_length +
                                year_factor+state_factor, x=T, y=T, data = senate_para_abortion)
# Clustering by state
para_level_logit_legal_robust <- robcov(para_level_logit_legal, cluster=senate_para_abortion$state_factor)

# Paragraph-level regression of use of legislative language as function of theoretical predictors; logistic regression; year and state fixed effects
para_level_logit_legislation <- lrm(act ~ republican + republican_post_2018 + majority_party + marginal * up_for_election + extremity + 
                                      on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_message_length +
                                      year_factor+state_factor, x=T, y=T, data = senate_para_abortion)
# Clustering by state
para_level_logit_legislation_robust <- robcov(para_level_logit_legislation, cluster=senate_para_abortion$state_factor)

# Stargazer
stargazer(para_level_logit_legal_robust, para_level_logit_legislation_robust,
          digits = 2,
          covariate.labels = c("Republican",
                               "Republican x Post-2018",
                               "Majority Party",
                               "Marginal Senator",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "ln(Paragraph Length)",
                               "Marginal x Up for Election"),
          omit = c("state_factor=","year_factor="),
          dep.var.labels = c("Legal Rhetoric (Binary)", "Legislative Rhetoric (Binary)"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark"),
                           c("State-clustered SEs", "\\checkmark", "\\checkmark"),
                           c("Unit of Analysis", "Paragraph", "Paragraph")),
          title = "Legal and Legislative Rhetoric in Senator Messaging about Abortion Cases (Logistic Regression)",
          label = "abortion_logit_robust",
          font.size = "footnotesize")

##############################################################################
# Table H.5: Legal and Legislative Rhetoric, Alternative Marginality Measure #
##############################################################################
# Paragraph-level regression of use of legal language as function of theoretical predictors; alternative marginality measure; year and state fixed effects, clustering by state
para_level_alt_marginal <- felm(legal_language ~ republican + republican:post_2018 + majority_party + log_previous_vote_share * up_for_election + extremity + 
                                  on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_message_length|year+
                                  two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_para_abortion)
# Paragraph-level regression of use of legislative language as function of theoretical predictors; alternative marginality measure; year and state fixed effects, clustering by state
para_level2_alt_marginal <- felm(act ~ republican + republican:post_2018 + majority_party + log_previous_vote_share * up_for_election + extremity + 
                                   on_sjc + senator_lawyer + seniority + seniority.squared + freshman + log_message_length|year+
                                   two.letter.state.abbreviation|0|two.letter.state.abbreviation, data = senate_para_abortion)

# Stargazer table of results
stargazer(para_level_alt_marginal, para_level2_alt_marginal,
          digits = 2,
          covariate.labels = c("Republican",
                               "Majority Party",
                               "Previous Vote Share (Log)",
                               "Up for Election",
                               "Extremity",
                               "On Judiciary Committee",
                               "Lawyer",
                               "Seniority",
                               "Seniority squared",
                               "Freshman",
                               "ln(Paragraph Length)",
                               "Republican x Post-2018",
                               "Previous Vote Share (Log) x Up for Election"),
          dep.var.labels = c("Legal Rhetoric", "Legislative Rhetoric"),
          style = "apsr",
          keep.stat = c("n", "adj.rsq"),
          add.lines = list(c("Year FEs", "\\checkmark", "\\checkmark"),
                           c("State FEs", "\\checkmark", "\\checkmark"),
                           c("State-clustered SEs", "\\checkmark", "\\checkmark"),
                           c("Unit of Analysis", "Paragraph", "Paragraph")),
          title = "Legal and Legislative Rhetoric in Senator Messaging about Abortion Cases, Alternative Marginality Measure",
          label = "abortion_felm_para_alt_marginal",
          font.size = "footnotesize")

